#ifndef SCT_RTSPSERVER_RTSPSERVER_H
#define SCT_RTSPSERVER_RTSPSERVER_H

#include <sstream>

#include <fcntl.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <pthread.h>

#include "RTSPServer.hh"
#include "liveMedia.hh"
#include "BasicUsageEnvironment.hh"

#include "sct/core/common.h"
#include "sct/rtspserver/rtspserverinterface.h"
#include "sct/rtspserver/serverinterface.h"

#include "sct/rtspserver/h264videoservermediasubsession.h"
#include "sct/rtspserver/h264streamsource.h"

#include "sct/rtspserver/aacservermediasubsession.h"
#include "sct/rtspserver/aacstreamsource.h"

#include "sct/rtspserver/amrservermediasubsession.h"
#include "sct/rtspserver/streamsource.h"

#include "sct/rtspserver/tsservermediasubsession.h"
#include "sct/rtspserver/tsstreamsource.h"

namespace sct
{

class CMyRTSPServer: public RTSPServer
{
public:
	static CMyRTSPServer* createNew(UsageEnvironment& env, Port ourPort = 554,
		       UserAuthenticationDatabase* authDatabase = NULL,
		       unsigned reclamationSeconds = 65);

	inline int nClients(){return mRef;}
protected:
	CMyRTSPServer(UsageEnvironment& env,
		     int ourSocket, Port ourPort,
		     UserAuthenticationDatabase* authDatabase,
		     unsigned reclamationSeconds);

	virtual ~CMyRTSPServer();
	virtual ClientSession* createNewClientSession(u_int32_t sessionId);


public:
	class CMyRTSPClientSession: public RTSPClientSession
	{
		friend class CMyRTSPServer;
	protected:
		CMyRTSPClientSession(CMyRTSPServer& ourServer, u_int32_t sessionId);
		virtual ~CMyRTSPClientSession();

	private:

		CMyRTSPServer * mServer;
	};

	int mRef;
};


class CServerMediaSubsession
{
public:
	CRTSPServerInterface::Type type;
	CStreamSource * source;
};

class CServerMediaSession
{
public:
	std::list<CServerMediaSubsession*> subsessions;
	std::string path;
	ServerMediaSession * server_media_session;
	std::string url;
};

class CRTSPServer: public CRTSPServerInterface, public CServerInterface
{
public:
	CRTSPServer(const int port);
	virtual ~CRTSPServer();

	virtual CServerMediaSession* createServerMediaSession(
				const char* path);
	virtual CServerMediaSubsession* createServerMediaSubsession(
				CServerMediaSession* session, const CStreamInfo & info);
	virtual void init();
	virtual const char* getUrl(CServerMediaSession* session);
	virtual void putMediaData(CServerMediaSubsession* subsession,
			const void*p, const int len, const int64_t pts);

	inline bool needStopStream(){return 0 == mServer->nClients();}
private:
	static void* rtsp(void * arg);

	void initServerMediaSubsession(CServerMediaSession*session);

private:
	enum State
	{
		Running = 0,
		Terminated,
	};

private:
	pthread_t mThdserver;
	char mState;

	int mPort;
	std::list<CServerMediaSession*> mSessions;
	BasicUsageEnvironment* mEnv;
	CMyRTSPServer *mServer;
	BasicTaskScheduler *mSched;
};


}



#endif
